---
title: 'useSnapshot'
section: 'API'
subSection: 'Basic'
description: 'Create a local snapshot that catches changes.'
---

# useSnapshot

Create a local snapshot that catches changes.

Normally, Valtio's snapshots (created via <a href="/docs/api/advanced/snapshot">`snapshot()`</a>) are recreated on _any_ change to a proxy, or any of its child proxies.

However `useSnapshot` wraps the Valtio snapshot in an access-tracking proxy, so your component is render optimized, i.e. it will only re-render if keys that it (or its child components) specifically accessed have changed, and not on every single change to the proxy.

## Usage

### Read from snapshots in render, use the proxy in callbacks

Snapshots are read-only to render the JSX from their consistent view of the data.

Mutations, and also any reads in callbacks that make mutations, need to be made via the proxy, so that the callback reads & writes the latest value.

```jsx
function Counter() {
  const snap = useSnapshot(state)
  return (
    <div>
      {snap.count}
      <button
        onClick={() => {
          // also read from the state proxy in callbacks
          if (state.count < 10) {
            ++state.count
          }
        }}
      >
        +1
      </button>
    </div>
  )
}
```

### Parent/Child Components

If you have a parent component use `useSnapshot`, it can pass snapshots to child components and the parent & children will re-render when the snapshot changes.

For example:

```jsx
const state = proxy({
  books: [
    { id: 1, title: 'b1' },
    { id: 2, title: 'b2' },
  ],
})

function AuthorView() {
  const snap = useSnapshot(state)
  return (
    <div>
      {snap.books.map((book) => (
        <Book key={book.id} book={book} />
      ))}
    </div>
  )
}

function BookView({ book }) {
  // book is a snapshot
  return <div>{book.title}</div>
}
```

If book 2's title is changed, a new `snap` is created and the `AuthorView` and `BookView` components will re-render.

Note if `BookView` is `React.memo`d, the 1st `BookView` will not re-render, b/c the 1st `Book` snapshot will be the same instance, as only the 2nd `Book` was mutated (the root `Author` snapshot will also be updated since the list of `books` has changed).

### Child Components Making Mutations

The above approach works if `BookView` is read-only; if your child component needs to make mutations, then you'll need to pass the proxy:

```jsx
function AuthorView() {
  const snap = useSnapshot(state)
  return (
    <div>
      {snap.books.map((book, i) => (
        <Book key={book.id} book={state.books[i]} />
      ))}
    </div>
  )
}

function BookView({ book }) {
  // book is the proxy, so we can re-snap it + mutate it
  const snap = useSnapshot(book)
  return <div onClick={() => book.updateTitle()}>{snap.title}</div>
}
```

Or you can pass both the snapshot and proxy together, if you don't want to call `useSnapshot` in the child component:

```jsx
function AuthorView() {
  const snap = useSnapshot(state)
  return (
    <div>
      {snap.books.map((book, i) => (
        <Book key={book.id} bookProxy={state.books[i]} bookSnapshot={book} />
      ))}
    </div>
  )
}
```

There should be no performance difference between these two approaches.

### Read only what you need

Every object inside your proxy also becomes a proxy (if you don't use <a href="/docs/advanced/ref">`ref()`</a>). So you can also use them to create
a local snapshot.

```jsx
function ProfileName() {
  const snap = useSnapshot(state.profile)
  return <div>{snap.name}</div>
}
```

### Gotchas

Beware of replacing the child proxy with something else, breaking your snapshot. You can see
here what happens with the original proxy when you replace the child proxy.

```js
console.log(state)
{
  profile: {
    name: 'valtio'
  }
}
childState = state.profile
console.log(childState)
{
  name: 'valtio'
}
state.profile.name = 'react'
console.log(childState)
{
  name: 'react'
}
state.profile = { name: 'new name' }
console.log(childState)
{
  name: 'react'
}
console.log(state)
{
  profile: {
    name: 'new name'
  }
}
```

`useSnapshot()` depends on the original reference of the child proxy so if you replace it with a new one, the component
that is subscribed to the old proxy won't receive new updates because it is still subscribed to the old one.

In this case, we recommend one of the approaches below. In neither example do you need to worry about re-renders because it is render-optimized.

```jsx
const snap = useSnapshot(state)

return <div>{snap.profile.name}</div>
```

```jsx
const { profile } = useSnapshot(state)

return <div>{profile.name}</div>
```

### Dev Mode Debug Values

In dev mode, `useSnapshot` uses React's `useDebugValue` to output a list of fields that were accessed during rendering, i.e. which specific fields will trigger re-render when the tracking proxy changes.

There are two disclaimers to the debug value:

1. Due to the way `useSnapshot` uses a proxy to recorded accesses _after_ `useSnapshot` has returned, the fields listed in `useDebugValue` are technically from the _previous_ render.
2. Object getter and class getter calls are not included in the `useDebugValue` output, but don't worry, they are actually correctly tracked internally and correctly trigger re-renders when changed.

## Codesandbox demo

https://codesandbox.io/s/ping-pong-with-valtio-wb25s?file=/src/App.js
